<template>
  <div
    id="screenfull-container-m3"
    ref="screenfull"
    class="container"
    :class="{ 'screenfull-container': isFullscreen }"
  >
    <ButtonGroup
      v-if="buttons.length && !isFullscreen"
      class="button-container"
      :options="buttons"
      @click="handleButtonClick"
    />
    <ScreenfullHead />
    <SearchDetailForm
      ref="form"
      :sale-group-options="saleGroupOptions"
      :has-export="false"
      @search="onSearch"
    />
    <p-table
      row-key="id"
      :custom-header-row="isEdit ? customHeaderRowMinxin : undefined"
      :columns="columns"
      bordered
      :scroll="{ x: '100%', y: isFullscreen ? 'calc(100vh - 300px' : 300 }"
      :pagination="false"
      :data-source="totalData"
      :row-selection="rowSelection"
      @change="handleTableChange"
    />
    <DialogFiledFilter
      :visible.sync="visibleFiled"
      :get-container="getContainer"
      :fileds="fileds"
      :local-key="localKey"
      :default-show="defaultShow"
      :default-fixed="defaultFixed"
      :show.sync="filedShowKeys"
      :fixed.sync="filedFixedKeys"
    />
    <DialogUploadForecast
      ref="upload"
      :plan-id="planId"
      :type="M_TEMPLATE['m3fcst']"
      @change="handleInsertChange"
    />

    <DialogM9RelationList
      :value="currentRowInfo.value"
      :get-container="getContainer"
      :visible="visibleM9Id"
      :time-range="timeRange"
      :has-more="true"
      :is-edit="isEdit"
      :condition="condition"
      @cancel="(val) => (visibleM9Id = val)"
      @change="(e) => confirmDialog(e)"
    />

    <DialogUserList
      :value="currentRowInfo.value"
      :get-container="getContainer"
      :visible="visibleCustomer"
      @cancel="(val) => (visibleCustomer = val)"
      @change="(e) => confirmDialog(e)"
    />
    <DialogChooseModelType
      :value="currentRowInfo.value"
      :get-container="getContainer"
      :visible="visibleModelNumber"
      @cancel="(val) => (visibleModelNumber = val)"
      @change="(e, modelCutRate) => confirmDialog(e, modelCutRate)"
    />
    <DialogModelNameList
      :value="currentRowInfo.value"
      :get-container="getContainer"
      :visible="visibleModelName"
      :info="currentRowInfo"
      @cancel="(val) => (visibleModelName = val)"
      @change="(e) => confirmDialog(e)"
    />
  </div>
</template>

<script>
import mixinTable from '@/mixins/mixin-table.js';
import { createWeekArray } from '@/utils/time';
import DialogUserList from '@/components/dialog/DialogUserList.vue';
import DialogChooseModelType from '@/components/dialog/DialogChooseModelType.vue';
import DialogM9RelationList from '@/components/dialog/DialogM9RelationList.vue';
import DialogModelNameList from '@/components/dialog/DialogModelNameList.vue';
import DialogFiledFilter from '@/components/dialog/DialogFiledFilter.vue';
import Decimal from 'decimal.js';
import SearchDetailForm from '@/components/search/SearchDetailForm.vue';
import screenfull from '@/utils/screenfull';
import {
  postReuseDetailList,
  postExportDetailTemplate,
  postExportDetail,
  getLastFcst,
  getLastDetailInfo,
  getM9RelationList,
} from '@/api/forecast';
import { transferDataDetail } from './utils';
import { downloadFile } from '@/utils/index.js';
import DialogUploadForecast from '@/components/dialog/DialogUploadForecast.vue';

import { M_TEMPLATE } from '@/constants/index';
import { isEmpty } from '@/utils/is';

import _ from 'lodash';
import moment from 'moment';
let index = 0;

export default {
  components: {
    DialogFiledFilter,
    DialogUploadForecast,
    DialogM9RelationList,
    DialogUserList,
    DialogChooseModelType,
    DialogModelNameList,
    SearchDetailForm,
  },
  mixins: [mixinTable],
  props: {
    activeTab: {
      type: String,
      default: '',
    },
    pageType: {
      type: [String, Number],
      default: '',
    },
    localKey: {
      type: String,
      required: true,
    },
    defaultShow: {
      type: Array,
      default: () => [
        'mforecastSalesId',
        'customerCode',
        'modelNumber',
        'application',
      ],
    },
    defaultFixed: {
      type: Array,
      default: () => [
        'mforecastSalesId',
        'customerCode',
        'modelNumber',
        'application',
      ],
    },
    parentId: {
      type: [String, Number],
      default: undefined,
    },
    timeRange: {
      type: Array,
      default: () => ['2021-01', '2021-05'],
    },
    hideKeys: {
      type: Array,
      default: () => ['mforecastSalesId'],
    },
    dataSource: {
      type: Array,
      default: () => [],
    },
    isTotal: {
      type: Boolean,
      default: true,
    },
    detailCopy: {
      type: Array,
      default: () => [],
    },
    mforecastSalesId: {
      type: [Number, String],
      default: undefined,
    },
    planSales: {
      type: Array,
      default: () => [],
    },
    planId: {
      type: Number,
      default: 0,
    },
    isEdit: {
      type: Boolean,
      default: true,
    },
    hasCompare: {
      type: Boolean,
      default: false,
    },
    buttons: {
      type: Array,
      default: () => [
        {
          key: 'add',
          type: 'primary',
          label: '新增',
          icon: 'plus',
        },
        // {
        //   key: 'copy',
        //   label: '复用',
        // },
        {
          key: 'delete',
          label: '删除',
        },
        {
          key: 'insert',
          label: '导入',
        },
        {
          key: 'download',
          label: '下载模板',
        },
        {
          key: 'compare',
          label: '版本差异比对',
        },
        {
          key: 'relation',
          label: '关联M9关系ID',
        },
        {
          key: 'show',
          label: '显示字段',
        },
        // {
        //   key: 'screenfull',
        //   label: '全屏显示',
        // },
      ],
    },
  },
  data() {
    this.M_TEMPLATE = M_TEMPLATE;
    return {
      visibleFiled: false,
      visibleCustomer: false,
      visibleModelNumber: false,
      visibleM9Id: false,
      visibleModelName: false,
      filedsKeys: [],
      currentRowInfo: {},
      checkedGroups: {},
      filedShowKeys: [],
      filedFixedKeys: [],
      dataSourceFilter: [],
      isFullscreen: false,
      lastTimeRange: [],
      condition: {},
    };
  },
  computed: {
    rowSelection() {
      if (this.isEdit) return this.rowSelectionMixin;
      return false;
    },
    totalIndex() {
      return this.totalData.reduce((pre, cur, index) => {
        if (cur.id === 'totalKey') {
          pre.push(index);
        }
        return pre;
      }, []);
    },
    groups() {
      const data = this.dataSourceFilter.reduce((pre, cur) => {
        if (pre[cur.mforecastSalesId]) {
          pre[cur.mforecastSalesId].push(cur);
        } else {
          pre[cur.mforecastSalesId] = [cur];
        }
        return pre;
      }, {});
      Object.keys(data).forEach((group) => {
        data[group].forEach((item, index) => {
          item.index = index;
        });
      });
      return data;
    },
    totalData() {
      if (!this.dataSourceFilter.length) return [];
      const totalKeys = this.totalKeys;

      console.log('this.groups: ', this.groups);
      const data = Object.keys(this.groups).map((group) => {
        const obj = this.groups[group].reduce(
          (pre, cur) => {
            totalKeys.forEach((key) => {
              if (!_.get(pre, key)) {
                _.set(pre, key, 0);
              }
              const tempValue = new Decimal(_.get(pre, key)).plus(
                new Decimal(_.get(cur, key) || 0)
              );
              if (key.startsWith('price')) {
                _.set(pre, key, tempValue.toFixed(2));
              } else {
                _.set(pre, key, tempValue.toFixed());
              }
            });
            return pre;
          },
          { id: 'totalKey', changeRemark: '' }
        );
        return [...this.groups[group], { ...this.groups[group][0], ...obj }];
      });

      const obj = this.dataSourceFilter.reduce(
        (pre, cur) => {
          totalKeys.forEach((key) => {
            if (!_.get(pre, key)) {
              _.set(pre, key, 0);
            }
            const tempValue = new Decimal(_.get(pre, key)).plus(
              new Decimal(_.get(cur, key) || 0)
            );
            if (key.startsWith('price')) {
              _.set(pre, key, tempValue.toFixed(2));
            } else {
              _.set(pre, key, tempValue.toFixed());
            }
          });
          return pre;
        },
        { id: 'totalKey', changeRemark: '' }
      );

      if (Object.keys(this.groups).length > 1) {
        return [...data.flat(1), { ...this.dataSourceFilter[0], ...obj }];
      }
      return data.flat(1);
    },
    saleGroupOptions() {
      return this.planSales.map((item) => {
        return {
          value: item.id,
          label: item.salesGroupName,
        };
      });
    },
    ranges() {
      const weeks = createWeekArray(this.timeRange);
      return weeks;
    },
    lastRanges() {
      const ranges = createWeekArray(this.lastTimeRange);
      return ranges.filter((item) =>
        this.ranges.some((el) => item.date === el.date)
      );
    },
    monthObj() {
      const month = this.ranges.reduce((pre, cur) => {
        if (pre[cur.month]) {
          pre[cur.month].push(cur);
        } else {
          pre[cur.month] = [cur];
        }
        return pre;
      }, {});
      Object.keys(month).forEach((m) => {
        const week = month[m].reduce((pre, cur) => {
          if (pre[cur.week]) {
            pre[cur.week].push(cur);
          } else {
            pre[cur.week] = [cur];
          }
          return pre;
        }, {});
        const arr = Object.keys(week)
          .map((item) => {
            const s = week[item] && week[item][0].date;
            const e = week[item] && week[item][week[item].length - 1].date;
            return {
              week: item,
              start: moment(s),
              end: moment(e),
            };
          })
          .sort((a, b) => a.start - b.start)
          .map((item) => {
            return {
              ...item,
              start: item.start.format('MM/DD'),
              end: item.end.format('MM/DD'),
            };
          });
        month[m] = arr;
      });
      return month;
    },
    lastMonthObj() {
      const month = this.lastRanges.reduce((pre, cur) => {
        if (pre[cur.month]) {
          pre[cur.month].push(cur);
        } else {
          pre[cur.month] = [cur];
        }
        return pre;
      }, {});
      Object.keys(month).forEach((m) => {
        const week = month[m].reduce((pre, cur) => {
          if (pre[cur.week]) {
            pre[cur.week].push(cur);
          } else {
            pre[cur.week] = [cur];
          }
          return pre;
        }, {});
        const arr = Object.keys(week)
          .map((item) => {
            const s = week[item] && week[item][0].date;
            const e = week[item] && week[item][week[item].length - 1].date;
            return {
              week: item,
              start: moment(s),
              end: moment(e),
            };
          })
          .sort((a, b) => a.start - b.start)
          .map((item) => {
            return {
              ...item,
              start: item.start.format('MM/DD'),
              end: item.end.format('MM/DD'),
            };
          });
        month[m] = arr;
      });
      return month;
    },
    totalKeys() {
      const monthkeys = Object.keys(this.monthObj).map(
        (item) => `price.${item}`
      );
      const weekKeys = Object.keys(this.monthObj).reduce((pre, cur) => {
        const keys = this.monthObj[cur].map(
          (item) => `fcst.${cur}.${item.week}`
        );
        pre.push(...keys);
        return pre;
      }, []);
      return [...monthkeys, ...weekKeys];
    },
    colIndex() {
      return this.columns.findIndex((item) => item.dataIndex === 'fcst');
    },
    isAllChecked() {
      const checkedLength = Object.keys(this.checkedGroups).filter(
        (el) => this.checkedGroups[el]
      ).length;
      const groupsLenght = Object.keys(this.groups).length;
      return checkedLength === groupsLenght;
    },
    defaultCoulumns() {
      return [
        {
          align: 'center',
          title: '序号',
          dataIndex: 'index',
          width: 80,
          fixed: 'left',
          noOperate: true,
          customRender: (t, r, index) => {
            if (this.totalIndex.includes(index)) {
              return {
                children: (
                  <div style="display: flex;justify-content: flex-start;">
                    {index === this.totalData.length - 1 &&
                    Object.keys(this.groups).length > 1
                      ? '大汇总'
                      : '组内汇总'}
                  </div>
                ),
                attrs: {
                  colSpan: this.colIndex,
                },
              };
            }
            return parseInt(t) + 1;
          },
        },
        {
          align: 'center',
          title: (
            <p-checkbox
              checked={this.isAllChecked}
              vOn:change={this.handleCheckAll}
            />
          ),
          dataIndex: 'selection',
          width: 60,
          fixed: 'left',
          noOperate: true,
          isHide: this.hideKeys.includes('selection'),
          customRender: (value, row, index) => {
            const children = (
              <p-checkbox
                checked={this.checkedGroups[row.mforecastSalesId]}
                vOn:change={(e) => this.handleCheckBox(e, value, row, index)}
              />
            );
            return this.customRender(children, index, row, 'selection');
          },
        },
        {
          align: 'center',
          title: '销售组',
          dataIndex: 'mforecastSalesId',
          required: true,
          width: 120,
          isHide: this.hideKeys.includes('mforecastSalesId'),
          customRender: (value, row, index) => {
            // let children = <TableSpan value={value} />;
            // if (this.isEdit) {
            const children = (
              <SelectDefault
                value={value}
                get-popup-container={this.getContainer}
                disabled={!this.isEdit}
                options={this.saleGroupOptions}
                allow-clear={false}
                has-all={false}
                vOn:input={(e) =>
                  this.handleInputChange(
                    e,
                    value,
                    row,
                    index,
                    'mforecastSalesId'
                  )
                }
              />
            );
            // }
            return this.customRender(children, index, row, 'mforecastSalesId');
          },
        },
        {
          align: 'center',
          title: 'M+3关系ID',
          dataIndex: 'relationId',
          width: 160,
          isHide: this.hideKeys.includes('relationId'),
          customRender: (value, row, index) => {
            const children = (
              <InputDefault
                value={value}
                isEdit={this.isEdit}
                vOn:change={(e) =>
                  this.handleInputChange(e, value, row, index, 'relationId')
                }
              />
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '关联M+9关系ID',
          dataIndex: 'm9RelationId',
          width: 120,
          customRender: (value, row, index) => {
            const children = (
              <div>
                <InputSearch
                  value={{ key: value, label: value }}
                  isEdit={this.isEdit}
                  isLink={!this.isEdit}
                  vOn:search={() =>
                    this.openDialog('visibleM9Id', {
                      value,
                      row,
                      index,
                      dataIndex: 'm9RelationId',
                    })
                  }
                />
              </div>
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '厂别',
          dataIndex: 'factoryCode',
          required: true,
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <SelectDefault
                value={value}
                get-popup-container={this.getContainer}
                disabled={!this.isEdit}
                code="factory_code"
                allow-clear={false}
                has-all={false}
                vOn:input={(e) =>
                  this.handleInputChange(e, value, row, index, 'factoryCode')
                }
              />
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '客户简称',
          dataIndex: 'customerCode',
          required: true,
          width: 120,
          scopedSlots: { customRender: 'customerCode' },
          customRender: (value, row, index) => {
            const children = (
              <div>
                <InputSearch
                  value={value}
                  isEdit={this.isEdit}
                  vOn:search={() =>
                    this.openDialog('visibleCustomer', {
                      value,
                      row,
                      index,
                      dataIndex: 'customerCode',
                    })
                  }
                />
              </div>
            );
            return this.customRender(children, index);
          },
        },

        {
          align: 'center',
          title: '机种',
          dataIndex: 'modelNumber',
          required: true,
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <div>
                <InputSearch
                  value={value}
                  width={'120px'}
                  isEdit={this.isEdit}
                  vOn:search={() =>
                    this.openDialog('visibleModelNumber', {
                      value,
                      row,
                      index,
                      dataIndex: 'modelNumber',
                    })
                  }
                  vOn:change={(e) =>
                    this.handleInputChange(e, value, row, index, 'modelNumber')
                  }
                />
              </div>
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: 'Model Name',
          dataIndex: 'modelName',
          required: true,
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <div>
                <InputSearch
                  value={value}
                  isInput={true}
                  isEdit={this.isEdit}
                  vOn:search={() =>
                    this.openDialog('visibleModelName', {
                      value,
                      row,
                      index,
                      dataIndex: 'modelName',
                    })
                  }
                  vOn:change={(e) =>
                    this.handleInputChange(e, value, row, index, 'modelName')
                  }
                />
              </div>
            );
            return this.customRender(children, index);
          },
        },

        {
          align: 'center',
          title: '生产地',
          dataIndex: 'manufactureArea',
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <SelectDefault
                value={value}
                get-popup-container={this.getContainer}
                code="production_place"
                has-all={false}
                disabled={!this.isEdit}
                vOn:input={(e) =>
                  this.handleInputChange(
                    e,
                    value,
                    row,
                    index,
                    'manufactureArea'
                  )
                }
              />
            );

            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '应用别',
          dataIndex: 'application',
          required: true,
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <SelectDefault
                value={value}
                get-popup-container={this.getContainer}
                disabled={!this.isEdit}
                code="application"
                allow-clear={false}
                has-all={false}
                vOn:input={(e) =>
                  this.handleInputChange(e, value, row, index, 'application')
                }
              />
            );
            return this.customRender(children, index);
          },
        },

        {
          align: 'center',
          title: '模切比',
          required: true,
          dataIndex: 'modelCutRate',
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <InputInteger
                value={value}
                isEdit={this.isEdit}
                min={0}
                vOn:change={(e) =>
                  this.handleInputChange(e, value, row, index, 'modelCutRate')
                }
              />
            );

            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '形态',
          dataIndex: 'appearance',
          required: true,
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <SelectDefault
                value={value}
                get-popup-container={this.getContainer}
                code="shape"
                disabled={!this.isEdit}
                allow-clear={false}
                has-all={false}
                vOn:input={(e) =>
                  this.handleInputChange(e, value, row, index, 'appearance')
                }
              />
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '客户项目',
          dataIndex: 'item',
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <InputDefault
                value={value}
                isEdit={this.isEdit}
                vOn:change={(e) =>
                  this.handleInputChange(e, value, row, index, 'item')
                }
              />
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '内部项目',
          dataIndex: 'innerItem',
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <InputDefault
                value={value}
                isEdit={this.isEdit}
                vOn:change={(e) =>
                  this.handleInputChange(e, value, row, index, 'innerItem')
                }
              />
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '类别',
          dataIndex: 'category',
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <SelectDefault
                value={value}
                get-popup-container={this.getContainer}
                disabled={!this.isEdit}
                code="category"
                has-default={false}
                allow-clear={true}
                has-all={false}
                vOn:input={(e) =>
                  this.handleInputChange(e, value, row, index, 'category')
                }
              />
            );
            return this.customRender(children, index);
          },
        },
        {
          align: 'center',
          title: '备注',
          dataIndex: 'remark',
          width: 160,
          customRender: (value, row, index) => {
            const children = (
              <InputDefault
                value={value}
                isEdit={this.isEdit}
                vOn:change={(e) =>
                  this.handleInputChange(e, value, row, index, 'remark')
                }
              />
            );

            return this.customRender(children, index);
          },
        },
        // {
        //   align: 'center',
        //   title: 'FCST',
        //   dataIndex: 'fcst',
        //   required: true,
        //   children: this.createWeekColumns('fcst'),
        // },
        ...this.createWeekColumns('fcst'),
        ...this.createLastWeekColumns('lastFcst'),
        {
          align: 'center',
          title: '需求变动说明',
          dataIndex: 'changeRemark',
          width: 160,
          noOperate: true,
          isHide: this.lastRanges.length < 1,
          customRender: (value, row, index) => {
            const fcst = row.fcst || {};
            const lastFcst = row.lastFcst || {};
            const isSame = Object.keys(lastFcst).every((item) => {
              const last = JSON.stringify(lastFcst[item]);
              const current = JSON.stringify(fcst[item]);
              return last === current;
            });
            const isDiff =
              this.isEdit &&
              row.id !== 'totalKey' &&
              this.hasCompare &&
              !isSame;
            const children = (
              <InputDefault
                value={value}
                isEdit={isDiff}
                vOn:change={(e) =>
                  this.handleInputChange(e, value, row, index, 'changeRemark')
                }
              />
            );
            return this.customRender(children, index, row, 'changeRemark');
          },
        },
        {
          align: 'center',
          title: '单价（人民币：元）',
          dataIndex: 'price',
          // required: true,
          noOperate: true,
          children: this.createMonthColumns('price', false),
        },
      ];
    },
    fileds() {
      return this.defaultCoulumns;
    },
    columns() {
      let columns = this.defaultCoulumns.filter((item) => !item.isHide);
      if (this.filedShowKeys.length) {
        columns = columns.filter((item) => {
          return (
            item.required ||
            this.filedShowKeys.includes(item.dataIndex) ||
            item.noOperate
          );
        });
      }
      const left = [],
        right = [];
      columns.forEach((item) => {
        if (
          item.fixed === 'left' ||
          this.filedFixedKeys.includes(item.dataIndex)
        ) {
          left.push({ ...item, fixed: 'left' });
        } else {
          right.push(item);
        }
      });
      return [...left, ...right];
    },
  },
  watch: {
    dataSource: {
      handler(val) {
        this.onSearch();
      },
      immediate: true,
    },
    activeTab: {
      handler(val) {
        this.checkedGroups = [];
        this.$emit('checked', this.checkedGroups, this.groups);
      },
    },
  },
  created() {
    this.createDefaultItem();
    this.rowSelectionMixin.getCheckboxProps = (record) => {
      return {
        props: {
          disabled: record.id === 'totalKey',
        },
      };
    };
    this.handleCheckAll({ target: { checked: true } });
  },
  mounted() {
    this.getLastDetailInfo();
    this.onSearch();
    screenfull.onchange((e) => {
      this.isFullscreen = screenfull.isFullscreen;
    });
  },
  methods: {
    async relationCallback() {
      if (!this.dataSource.length) {
        this.$message.error('无可操作数据！');
        return;
      }
      const condition = this.dataSource.map((row) => {
        const mforecastSalesId = row?.mforecastSalesId;
        const customerCode = row.customerCode?.key;
        const modelName = row?.modelName?.label;
        return {
          mforecastSalesId,
          modelName,
          customerCode,
          mforecastId: this.planId,
          type: 1,
          // 实际是id
          createUserName: row.id,
        };
      });
      const isVaild = condition.some((item) => {
        if (
          isEmpty(item.mforecastSalesId) ||
          isEmpty(item.customerCode) ||
          isEmpty(item.modelName)
        ) {
          return true;
        }
        return false;
      });
      if (isVaild) {
        this.$message.error('客户简称、Model Name未填写完整，请补充！');
        return;
      }
      const result = await getM9RelationList(condition);

      const data = result?.data?.data || [];

      const map = data.reduce((pre, cur) => {
        const list = cur.mforecastDetailList || [];

        pre[cur.createUserName] =
          list.length > 1 ? undefined : list[0]?.relationId;
        return pre;
      }, {});

      const newData = this.dataSource.map((item) => {
        return {
          ...item,
          m9RelationId: map[item.id],
        };
      });
      this.dataSource.splice(0, this.dataSource.length, ...newData);
      this.$message.success('操作成功！');
    },
    async getLastDetailInfo() {
      const result = await getLastDetailInfo({ id: this.planId });
      const data = result?.data?.data || {};
      this.lastTimeRange = [data.startTime, data.endTime];
      // this.lastTimeRange = ['2021-09-01 00:00:00', '2021-10-01 00:00:00'];
    },
    async compareCallback() {
      const params = this.dataSource.map((item) => {
        return {
          mforecastSalesId: item.mforecastSalesId,
          customerCode: item.customerCode?.key,
          modelName: item.modelName?.label,
          id: item.id,
          type: this.pageType,
        };
      });
      const isPart = params.some((item) => {
        return Object.keys(item).some(
          (key) => item[key] === undefined || item[key] === ''
        );
      });
      if (isPart) {
        this.$message.error('客户简称、Model Name未填写完整，请补充后再试！');
        return;
      }

      const result = await getLastFcst({ id: this.planId }, params);
      const data = result?.data?.data || [];
      this.$emit('update:has-compare', true);
      const months = Object.keys(this.lastMonthObj);
      const map = data.reduce((pre, cur) => {
        const value = JSON.parse(cur.lastFcst || '{}');
        pre[cur.id] = Object.keys(value).reduce((p, c) => {
          if (months.includes(c)) {
            p[c] = value[c];
          }
          return p;
        }, {});
        return pre;
      }, {});
      const newData = this.dataSource.map((item) => {
        return {
          ...item,
          lastFcst: map[item.id],
        };
      });
      this.dataSource.splice(0, this.dataSource.length, ...newData);
      this.$message.success('操作成功！');
    },

    getContainer() {
      return document.getElementById('screenfull-container-m3');
    },
    onSearch(isSearch) {
      if (!this.$refs.form) return;
      if (!isSearch) {
        this.$refs.form.handleReset();
        return;
      }
      const form = (this.$refs.form && this.$refs.form.form) || {};
      const isEmpty = (val) => !val;
      // 销售组
      const isPlanSalesId = (val) =>
        isEmpty(form.planSalesId) || form.planSalesId === val;
      // 应用别
      const isApplication = (val) =>
        isEmpty(form.application) || form.application === val;
      // 形态
      const isAppearance = (val) =>
        isEmpty(form.appearance) || form.appearance === val;
      // 生产地
      const isManufactureArea = (val) =>
        isEmpty(form.manufactureArea) || form.manufactureArea === val;
      // Model Name
      const isModelName = (val) =>
        isEmpty(form.modelName) || val?.includes(form.modelName);
      // 机种
      const isModelNumber = (val) =>
        isEmpty(form.modelNumber) || val?.includes(form.modelNumber);
      // 客户简称 customerCode
      const isCustomerCode = (val) =>
        isEmpty(form.customerCode) || val?.includes(form.customerCode);
      this.dataSourceFilter = this.dataSource.filter((item) => {
        return (
          isPlanSalesId(item.mforecastSalesId) &&
          isApplication(item.application) &&
          isAppearance(item.appearance) &&
          isManufactureArea(item.manufactureArea) &&
          isModelName(item.modelName?.label) &&
          isModelNumber(item.modelNumber?.label) &&
          isCustomerCode(item.customerCode?.label)
        );
      });
      // 重置选择的状态
      this.checkedGroups = [];
      this.$emit('checked', this.checkedGroups, this.groups);
    },
    async screenfullCallback() {
      const ele = this.$refs.screenfull;
      if (screenfull.isEnabled) {
        await screenfull.toggle(ele, { navigationUI: 'hide' });
      }
    },
    handleCheckAll(e) {
      const checked = e.target.checked;
      Object.keys(this.groups).forEach((group) => {
        this.$set(this.checkedGroups, group, checked);
      });
      this.$emit('checked', this.checkedGroups, this.groups);
    },
    handleCheckBox(e, value, row) {
      const checked = e.target.checked;
      this.$set(this.checkedGroups, row.mforecastSalesId, checked);
      this.$emit('checked', this.checkedGroups, this.groups);
    },
    openDialog(dialog, rowInfo) {
      if (dialog === 'visibleM9Id') {
        const relationId = rowInfo?.row?.m9RelationId;
        const mforecastSalesId = rowInfo?.row?.mforecastSalesId;
        const salesGroupName = this.saleGroupOptions.find(
          (item) => item.value === mforecastSalesId
        )?.label;
        const customerCode = rowInfo?.row.customerCode?.key;
        const customerName = rowInfo?.row.customerCode?.label;
        const modelName = rowInfo?.row?.modelName?.label;
        if (
          isEmpty(mforecastSalesId) ||
          isEmpty(customerCode) ||
          isEmpty(modelName)
        ) {
          this.$message.error('客户简称、Model Name未填写完整，请补充！');
          return;
        }
        const condition = {
          salesGroupName,
          mforecastSalesId,
          modelName,
          customerCode,
          customerName,
          mforecastId: this.planId,
          relationId,
        };
        this.condition = condition;
      }
      this[dialog] = true;
      this.currentRowInfo = rowInfo;
    },
    confirmDialog(e, modelCutRate) {
      if (this.currentRowInfo.dataIndex === 'modelNumber') {
        this.handleInputChange(
          Number(modelCutRate) || '',
          this.currentRowInfo.value,
          this.currentRowInfo.row,
          this.currentRowInfo.index,
          'modelCutRate'
        );
      }
      this.handleInputChange(
        e,
        this.currentRowInfo.value,
        this.currentRowInfo.row,
        this.currentRowInfo.index,
        this.currentRowInfo.dataIndex
      );
    },
    customRender(children, index, row, key) {
      const attrs = {};
      if (this.totalIndex.includes(index)) {
        if (key === 'changeRemark') {
          attrs.colSpan = 1;
        } else {
          attrs.colSpan = 0;
        }
      }
      if (!this.isEdit && (key === 'mforecastSalesId' || key === 'selection')) {
        const data = this.groups[row.mforecastSalesId];
        if (row.id === data[0].id) {
          attrs.rowSpan = data.length;
        } else {
          attrs.rowSpan = 0;
        }
      }
      return {
        children,
        attrs,
      };
    },
    handleSelectFileds(filedsKeys) {
      this.filedsKeys = filedsKeys;
    },
    createDefaultItem() {
      console.log('this.monthObj: ', this.monthObj);
      const price = Object.keys(this.monthObj).reduce((pre, cur) => {
        pre[cur] = '';
        return pre;
      }, {});
      const fcst = Object.keys(this.monthObj).reduce((pre, cur) => {
        pre[cur] = this.monthObj[cur].reduce((p2, c2) => {
          p2[c2.week] = '';
          return p2;
        }, {});
        return pre;
      }, {});
      const lastFcst = Object.keys(this.lastMonthObj).reduce((pre, cur) => {
        pre[cur] = this.lastMonthObj[cur].reduce((p2, c2) => {
          p2[c2.week] = '';
          return p2;
        }, {});
        return pre;
      }, {});
      return {
        id: `${index++}_customer`,
        item: '',
        relationId: undefined,
        m9RelationId: undefined,
        factoryCode: '',
        category: '',
        mforecastSalesId: this.mforecastSalesId,
        innerItem: '',
        customerCode: { key: '', value: '' },
        modelNumber: { key: '', value: '' },
        modelName: { key: '', value: '' },
        application: '',
        appearance: '',
        manufactureArea: '',
        modelCutRate: '',
        remark: '',
        salesGroupName: '',
        price,
        fcst,
        lastFcst,
        changeRemark: '',
      };
    },
    totalAccount(type, record, index) {
      const value = _.get(record, type);
      const result = Object.keys(value || {}).reduce((pre, cur) => {
        if (cur !== 'total') {
          const n = Number(value[cur]) || 0;
          pre = pre.plus(new Decimal(n));
        }
        return pre;
      }, new Decimal(0));
      if (type === 'price') {
        return new Decimal(result).toFixed(2);
      }
      return new Decimal(result).toFixed();
    },
    createLastWeekColumns(key) {
      const customCell = () => ({
        style: {
          background: '#facd91',
        },
      });
      const columns = Object.keys(this.lastMonthObj).map((month) => {
        const monthItem = {
          align: 'center',
          dataIndex: 'lastFcst',
          noOperate: true,
          isHide: this.lastRanges.length < 1,
          title: `上一版本${moment(month).format(
            'YYYY年MM月'
          )}FCST（小片 Kpcs）`,
          customHeaderCell: customCell,
          customCell: customCell,
          children: [...this.lastMonthObj[month], 'total'].map((week) => {
            if (week === 'total') {
              const dataIndex = `${key}.${month}.${week}`;
              return {
                align: 'center',
                title: '',
                customHeaderCell: customCell,
                customCell: customCell,
                children: [
                  {
                    align: 'center',
                    title: '汇总',
                    width: 160,
                    dataIndex,
                    customHeaderCell: customCell,
                    customCell: customCell,
                    customRender: (text, row, index) => {
                      return (
                        <TableSpan
                          value={this.totalAccount(`${key}.${month}`, row)}
                        />
                      );
                    },
                  },
                ],
              };
            } else {
              const dataIndex = `${key}.${month}.${week.week}`;
              return {
                align: 'center',
                title: `WK${week.week}`,
                customHeaderCell: customCell,
                customCell: customCell,
                children: [
                  {
                    width: 160,
                    align: 'center',
                    title: `${week.start}-${week.end}`,
                    dataIndex,
                    customHeaderCell: customCell,
                    customCell: customCell,
                    customRender: (text, row, index) => {
                      return <TableSpan value={text} />;
                    },
                  },
                ],
              };
            }
          }),
        };
        return monthItem;
      });
      return columns;
    },

    createWeekColumns(key) {
      const columns = Object.keys(this.monthObj).map((month) => {
        const monthItem = {
          align: 'center',
          dataIndex: 'fcst',
          required: true,
          noOperate: true,
          title: `${moment(month).format('YYYY年MM月')}FCST（小片 Kpcs）`,
          children: [...this.monthObj[month], 'total'].map((week) => {
            if (week === 'total') {
              const dataIndex = `${key}.${month}.${week}`;
              return {
                align: 'center',
                title: '',
                children: [
                  {
                    align: 'center',
                    title: '汇总',
                    width: 160,
                    dataIndex,
                    customRender: (text, row, index) => {
                      return (
                        <TableSpan
                          value={this.totalAccount(`${key}.${month}`, row)}
                        />
                      );
                    },
                  },
                ],
              };
            } else {
              const dataIndex = `${key}.${month}.${week.week}`;
              const lastFcstDataIndex = `lastFcst.${month}.${week.week}`;
              return {
                align: 'center',
                title: `WK${week.week}`,
                required: true,
                children: [
                  {
                    width: 160,
                    align: 'center',
                    title: `${week.start}-${week.end}`,
                    dataIndex,
                    customRender: (text, row, index) => {
                      const lastFcst = _.get(row, lastFcstDataIndex);
                      return (
                        <InputInteger
                          value={text}
                          is-same={
                            text === lastFcst ||
                            isEmpty(lastFcst) ||
                            (row.id === 'totalKey' && lastFcst === '0')
                          }
                          isEdit={
                            this.isEdit && !this.totalIndex.includes(index)
                          }
                          min={-1}
                          vOn:change={(e) =>
                            this.handleObjectInputChange(
                              e,
                              text,
                              row,
                              index,
                              dataIndex
                            )
                          }
                        />
                      );
                    },
                  },
                ],
              };
            }
          }),
        };
        return monthItem;
      });
      return columns;
    },
    createMonthColumns(key, hasEdit) {
      const columns = Object.keys(this.monthObj).map((month) => {
        const dataIndex = `${key}.${month}`;
        const monthItem = {
          align: 'center',
          title: month,
          width: 150,
          dataIndex,
          customRender: (text, row, index) => {
            return (
              <InputNumber
                value={text}
                isEdit={
                  this.isEdit && !this.totalIndex.includes(index) && hasEdit
                }
                to-fixed={key === 'price' ? 2 : undefined}
                vOn:change={(e) =>
                  this.handleObjectInputChange(e, text, row, index, dataIndex)
                }
              />
            );
          },
        };
        return monthItem;
      });
      // const totalDataIndex = `${key}.total`;
      // columns.push({
      //   align: 'center',
      //   title: '汇总',
      //   width: 120,
      //   dataIndex: totalDataIndex,
      //   customRender: (text, row, index) => {
      //     return <TableSpan value={this.totalAccount(key, row)} />;
      //   },
      // });
      return columns;
    },
    handleInputChange(e, text, record, index, key) {
      const keys = ['mforecastSalesId', 'customerCode', 'modelName'];
      if (keys.includes(key)) {
        this.$emit('update:has-compare', false);
      }
      if (key === 'mforecastSalesId') {
        record.mforecastSalesId = e;
      }
      if (key === 'm9RelationId') {
        record.price = JSON.parse(e.price || '{}');
        record.m9RelationId = e.relationId;
        return;
      }

      record[key] = e;
    },
    handleObjectInputChange(e, text, record, index, key) {
      _.set(record, key, e);
    },
    handleButtonClick(key) {
      const fn = `${key}Callback`;
      this[fn] && this[fn]();
    },
    deleteCallback() {
      const ids = this.rowSelectionMixin.selectedRowKeys;
      if (!ids.length) {
        this.$message.error('请先选择数据！');
        return;
      }
      this.$confirm(`该操作将删除 ${ids.length} 条数据，是否确认？`)
        .then(() => {
          ids.forEach((id) => {
            const index = this.dataSource.findIndex((item) => item.id === id);
            this.dataSource.splice(index, 1);
          });
          this.rowSelectionMixin.selectedRowKeys = [];
        })
        .catch(() => {
          // console.log('e: ', e);
        });
    },
    addCallback() {
      this.dataSource.push({ ...this.createDefaultItem() });
    },
    async copyCallback() {
      const result = await postReuseDetailList({
        startTime: this.timeRange[0],
        endTime: this.timeRange[1],
        planId: this.planId,
        type: this.pageType,
      });
      const data = result?.data?.data || [];
      const formatData = transferDataDetail(data, this.timeRange);
      const changePlanSalesId = formatData.map((item) => {
        return {
          ...item,
          planSalesId: this.planSalesId,
          relationId: undefined,
        };
      });
      if (data.length) {
        if (this.dataSource.length) {
          this.$confirm('该操作将覆盖现有数据，是否确定？')
            .then((vaild) => {
              if (vaild) {
                // this.dataSource.push(...changePlanSalesId);

                this.dataSource.splice(
                  0,
                  this.dataSource.length,
                  ...changePlanSalesId
                );
                this.$message.success('操作成功！');
              }
            })
            .catch(() => {});
        } else {
          this.dataSource.splice(
            0,
            this.dataSource.length,
            ...changePlanSalesId
          );
          this.$message.success('操作成功！');
        }
      } else {
        this.$message.error('无可复用数据！');
      }
    },
    handleInsertChange(data) {
      if (data.length) {
        const formatData = transferDataDetail(data, this.timeRange);
        const changePlanSalesId = formatData.map((item) => {
          return {
            ...item,
            mforecastSalesId: item.mforecastSalesId
              ? item.mforecastSalesId
              : this.mforecastSalesId,
          };
        });
        if (this.dataSource.length) {
          this.$confirm('该操作将覆盖现有数据，是否确定？')
            .then((vaild) => {
              if (vaild) {
                this.dataSource.splice(
                  0,
                  this.dataSource.length,
                  ...changePlanSalesId
                );
                this.$message.success('操作成功！');
              }
            })
            .catch(() => {});
        } else {
          this.dataSource.splice(
            0,
            this.dataSource.length,
            ...changePlanSalesId
          );
          this.$message.success('操作成功！');
        }
      } else {
        this.$message.error('无可导入数据！');
      }
    },
    insertCallback() {
      this.$refs.upload?.uploader();
    },
    async downloadCallback() {
      const res = await postExportDetailTemplate({
        templateType: M_TEMPLATE['m3fcst'],
        id: this.planId,
        mforecastSalesId: this.mforecastSalesId,
      });
      await downloadFile(res.data, res.filename || '模板.xls');
    },
    async exportCallback() {
      const res = await postExportDetail({
        templateType: M_TEMPLATE['m3fcst'],
        id: this.planId,
        mforecastSalesId: this.mforecastSalesId,
        idList: this.dataSourceFilter.map((item) => item.id),
      });
      await downloadFile(res.data, res.filename || '明细.xls');
      // this.$message.error('导出功能暂未实现！');
    },
    showCallback() {
      this.visibleFiled = true;
    },
    getstartCallback() {
      this.$emit('getstart');
    },
    saveTemplateCallback() {
      // console.log('saveTemplateCallback: ', this.saveTemplateCallback);
      this.$message.success('cheng');
    },
  },
};
</script>

<style lang="less" scoped>
.button-container {
  margin-bottom: 20px;
}
.poros-table td {
  white-space: nowrap;
}
.container {
  margin-bottom: 20px;
}
.table-list-container {
  margin-top: 10px;
}
.screenfull-container {
  background: #fff;
  padding: 20px;
}
</style>